package com.kizuki.date;


import org.junit.Test;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.Set;

public class TestDate {

    @Test
    public void testLocalDateTime() {

        // 获取当前时间
        LocalDateTime time0 = LocalDateTime.now();
        // of 传参数
        LocalDateTime time1 = LocalDateTime.of(2020, 12, 25, 22, 14, 3);
        // 自定义格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        LocalDateTime time2 = LocalDateTime.parse("2020/02/01 01:01:01", dateTimeFormatter);
        // 时间戳
        LocalDateTime time3 = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());

        /**
         * 获得年月日
         * time0.getDayOfYear()
         * time0.getDayOfMonth()
         * time0.getDayOfWeek()
         */
        System.out.println(time0);
        System.out.println(time0.getDayOfMonth());
        System.out.println(time0.getDayOfWeek());

        LocalDateTime ldt2 = time1.plusDays(9);
        LocalDateTime ldt3 = time1.minusMonths(2);
        System.out.println("ldt2 = " + ldt2);
        System.out.println("ldt3 = " + ldt3);
        System.out.println("ldt2.isAfter(ldt3) = " + ldt2.isAfter(ldt3));
        System.out.println("ldt2.isBefore(ldt3) = " + ldt2.isBefore(ldt3));
    }

    /**
     * 线程不安全 配合ThreadLocal或者synchronized使用
     * 或者使用LocalDateTime
     */
    @Test
    public void testSimpleDateFormat() {
        ThreadLocal<SimpleDateFormat> simpleDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
        String time = simpleDateFormat.get().format(new Date());
        System.out.println(time);
    }

    @Test
    public void testInstant() {
        Instant now = Instant.now();
        System.out.println("new Date = " + new Date());
        /**
         * 这个默认时区不是我们的时区
         */
        System.out.println(now);

        OffsetDateTime odt = now.atOffset(ZoneOffset.ofHours(8));
        System.out.println(odt);
        /**
         * 2020-12-25T14:21:04.129Z
         * 2020-12-25T22:21:04.129+08:00
         */
        // Epoch 时期
        System.out.println(now.toEpochMilli());
        System.out.println(LocalDateTime.now());

        Instant ins1 = Instant.ofEpochSecond(now.toEpochMilli() / 1000);
        System.out.println(ins1);
    }

    @Test
    public void testDuration() {
        Instant before = Instant.now();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Instant after = Instant.now();

        Duration duration = Duration.between(before, after);
        System.out.println(duration.getSeconds());

        LocalTime lt0 = LocalTime.now();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        LocalTime lt1 = LocalTime.now();
        System.out.println(Duration.between(lt0, lt1));

//        LocalDate ld0 = LocalDate.now();
//        try {
//            Thread.sleep(2200);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//
//        LocalDate ld1 = LocalDate.now();
//        Duration d = Duration.between(ld0, ld1);
//        System.out.println(d);
//        会报错，不适用LocalDate，用Period

    }

    @Test
    public void testPeriod() {
        LocalDate ld0 = LocalDate.of(2020, 11, 11);
        LocalDate ld1 = LocalDate.now();
        Period period = Period.between(ld0, ld1);
        System.out.println(period);
        System.out.println(period.toTotalMonths());
        System.out.println(period.withYears(-1));
    }

    @Test
    public void testWith() {
        LocalDateTime ldt0 = LocalDateTime.now();
        System.out.println(ldt0);

        // 表示将ldt0调整当前day为month的第四天 下面同理
        LocalDateTime ldt1 = ldt0.withDayOfMonth(4);
        System.out.println(ldt1);
        LocalDateTime ldt2 = ldt0.with(TemporalAdjusters.firstDayOfMonth());
        System.out.println(ldt2);
        LocalDateTime ldt3 = ldt0.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
        System.out.println(ldt3);

        // with 传入函数式接口TemporalAdjuster 自定义调整时间规则
        LocalDateTime ldt4 = ldt0.with((l) -> {
            LocalDateTime ldt = (LocalDateTime) l;
            DayOfWeek dow = ldt.getDayOfWeek();
            if(dow.equals(DayOfWeek.SATURDAY)){
                return ldt.plusDays(2);
            } else {
                return ldt.plusDays(1);
            }
        });
        System.out.println(ldt4);
    }

    @Test
    public void testFormatter() {
        LocalDateTime ldt =  LocalDateTime.now();

        // DateTimeFormatter有很多内置格式
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_TIME;
        DateTimeFormatter f1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);

        System.out.println(ldt.format(formatter));
        System.out.println(formatter.format(ldt));

        System.out.println("----------------------------");

        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        String strDate = ldt.format(formatter1);
        System.out.println(strDate);
        System.out.println(formatter1.parse(strDate));
    }

    /**
     * 时区
     */
    @Test
    public void testZoneIds() {
        Set<String> zIds =  ZoneId.getAvailableZoneIds();
        zIds.forEach(System.out::println);
    }

    @Test
    public void testAtZone() {
        LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Europe/Brussels"));
        System.out.println(ldt);

        LocalDateTime ldt1 = LocalDateTime.now();
        System.out.println("ldt1 = " + ldt1);
        System.out.println("ldt1.atZone = " + ldt1.atZone(ZoneId.systemDefault()));
    }
}
